package com.masonluo.mlonlinejudge.typehandler;

import com.masonluo.mlonlinejudge.utils.EnumUtils;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 枚举类的通用TypeHandler类型
 * 使用这个TypeHandler，对枚举类型有要求，也就是枚举类型必须要有一个id属性
 * 无id属性会报错，因为需要根据id来获取Enum类型和将其id保存到数据库里面
 *
 * @author masonluo
 * @date 2020/12/27 5:20 下午
 */
public abstract class BaseEnumTypeHandler<T extends Enum<T>> implements TypeHandler<T> {
    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, T t, JdbcType jdbcType) throws SQLException {
        Integer id = EnumUtils.getEnumId(t);
        if (id == null) {
            throw new IllegalArgumentException("Can't obtain the id of enumeration class, The class is [" + getEnumClass().getName() + "]");
        }
        preparedStatement.setInt(i, id);
    }

    @Override
    public T getResult(ResultSet resultSet, String s) throws SQLException {
        int id = resultSet.getInt(s);
        return EnumUtils.getEnumById(getEnumClass(), id);
    }

    @Override
    public T getResult(ResultSet resultSet, int i) throws SQLException {
        int id = resultSet.getInt(i);
        return EnumUtils.getEnumById(getEnumClass(), id);
    }

    @Override
    public T getResult(CallableStatement callableStatement, int i) throws SQLException {
        int id = callableStatement.getInt(i);
        return EnumUtils.getEnumById(getEnumClass(), id);
    }

    /**
     * 子类需要实现这个方法，获取泛型的Class类型对象
     */
    protected abstract Class<T> getEnumClass();
}
